/*
 * VectorBigramas.cpp
 *
 *  Created on: Dec 8, 2014
 *      Author: ale
 */

#include "VectorBigramas.h"

VectorBigramas::VectorBigramas(VectorUnigramas *unis) {
	unigramas = unis;
	tam = 60000000;
	s_palabras = vector<unsigned int>(tam, 0); //vector<string>(tam, "");
	hist = vector<unsigned int>(tam, 0);
	probs = vector<float>(tam, 0.0);
	boffs = vector<float>(tam, 0.0);

	offsets = vector<istream::streampos>(tam, 0);

	mejor_trigrama_que_lo_completa = vector<unsigned int>(tam, 0);

}

VectorBigramas::~VectorBigramas() {
	// TODO Auto-generated destructor stub
}

unsigned int VectorBigramas::obtenerHash(const char* unigrama, size_t len){
	unsigned int hash = SuperFastHash(unigrama, len);

	return hash % tam;
}

//devuelve la posicion de la palabra en el vocabulario si esta o la nueva posicion si no esta
unsigned int VectorBigramas::buscarBigrama(string A, string B, size_t pos_histA, size_t posBenVocab){
	size_t pos = 0;
	//cout << A << endl;
	//cout << B << endl;
	string paHashear;
	paHashear = A+" "+B; //B.copy(paHashear, B.length(), 0);
	//size_t pos_histA = unigramas->buscarUnigrama(A, A.length());
	if (pos_histA != 0){
		pos = obtenerHash(paHashear.c_str(), paHashear.length());
		//size_t posBenVocab = unigramas->buscarUnigrama(B, B.length());
		size_t     skip = 0;
		while ((s_palabras[pos] != 0)){
			if ((hist[pos] == pos_histA) && (s_palabras[pos] == posBenVocab))
				return pos;
			pos = (pos + ++skip) % tam;
			//pos = (pos + 1) % tam;
		}
	}
	return pos % tam;
}

bool VectorBigramas::existeBigrama(string A, string B){
	size_t pos_histA = unigramas->buscarUnigrama(A, A.length());
	size_t posBenVocab = unigramas->buscarUnigrama(B, B.length());
	size_t pos = buscarBigrama(A, B, pos_histA, posBenVocab);
	return s_palabras[pos] != 0;
}

unsigned int VectorBigramas::agregarBigrama(string A, string B, double prob, double boff){
	//agregarla
	/*size_t pos = buscarBigrama(A, B);
	size_t pos_hist1 = unigramas->buscarUnigrama(A, A.length());
	s_palabras[pos] = unigramas->buscarUnigrama(B, B.length());//B;
	*/
	size_t pos = 0;
	size_t posBenVocab;
	string paHashear;
	paHashear = A+" "+B; //B.copy(paHashear, B.length(), 0);
	size_t posAenVocab = unigramas->buscarUnigrama(A, A.length());
	posBenVocab = unigramas->buscarUnigrama(B, B.length());
	pos = buscarBigrama(A, B, posAenVocab, posBenVocab);
	if ((pos != 0) && (posAenVocab != 0)){
		s_palabras[pos] = posBenVocab;
		hist[pos] = posAenVocab; //el indice de donde esta guardado la historia
		probs[pos] = prob;
		boffs[pos] = boff;
	}

	//cout << "Original: "+A+" "+B << endl;
	//cout << contenidoComoString(pos) << endl;

/*
	cout << unigramas->vocab[hist[pos]] << " "; // es == a unigramas->vocab[pos_hist1]
	cout << unigramas->vocab[s_palabras[pos]] << ": ";
	cout << "Original: "+A+" "+B << endl;
	cout << "prob " << pow(10,probs[pos]);
	cout << ", boffs " << pow(10,boffs[pos]) << endl;
*/
	return pos;
}

double VectorBigramas::obtenerProbabilidad(string A, string B){
	size_t pos_histA = unigramas->buscarUnigrama(A, A.length());
	size_t posBenVocab = unigramas->buscarUnigrama(B, B.length());
	size_t pos = buscarBigrama(A, B, pos_histA, posBenVocab);
	if (s_palabras[pos] != 0)
		return probs[pos];
	return 0;
}

double VectorBigramas::obtenerBackOff(string A, string B){
	size_t pos_histA = unigramas->buscarUnigrama(A, A.length());
	size_t posBenVocab = unigramas->buscarUnigrama(B, B.length());
	size_t pos = buscarBigrama(A, B, pos_histA, posBenVocab);
	if (s_palabras[pos] != 0)
		return boffs[pos];
	return 0;
}

void VectorBigramas::imprimirBigramas(){
	size_t i;
	for (i=0; i<tam; i++){
		if (s_palabras[i] == 0)
			continue;
		cout << unigramas->vocab[hist[i]] << " ";
		cout << unigramas->vocab[s_palabras[i]] << ": ";
		cout << "prob " << pow(10,probs[i]);
		cout << ", boffs " << pow(10,boffs[i]) << endl;
	}
}

string VectorBigramas::contenidoComoString(unsigned int i){
	return unigramas->vocab[hist[i]]+" "+unigramas->vocab[s_palabras[i]];

}

void VectorBigramas::agregarOffsetDeABenTrigramas(string A, string B, istream::streampos offset){
	size_t pos_histA = unigramas->buscarUnigrama(A, A.length());
	size_t posBenVocab = unigramas->buscarUnigrama(B, B.length());
	size_t pos = buscarBigrama(A, B, pos_histA, posBenVocab);
	offsets[pos] = offset;
}

bool VectorBigramas::agregarMejorTrigramaQueCompleta(string A, string B, string tercer_palabra){
	size_t pos_histA = unigramas->buscarUnigrama(A, A.length());
	size_t posBenVocab = unigramas->buscarUnigrama(B, B.length());
	size_t pos = buscarBigrama(A, B, pos_histA, posBenVocab);

	size_t posCenVocab = unigramas->buscarUnigrama(tercer_palabra, tercer_palabra.length());

	mejor_trigrama_que_lo_completa[pos] = posCenVocab;
	return true;
}
